package com.googlecode.olabs.gui.client;

import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.googlecode.olabs.gui.client.rest.RestRequestBuilder;

public class TestGui extends Composite {

	private static final String RADIO_GROUP_DESTINATION_TYPE = "destinationType";

	private TextBox m_cardNumber;
	private ListBox m_httpMethod;
	private TextArea m_postText;
	private TextBox m_urlDisplay;
	private RadioButton m_radioRoot;
	private TextArea m_httpResult;

	public TestGui() {
		final FlexTable mainTable = new FlexTable();
		initWidget(mainTable);

		// 'To' section
		mainTable.setWidget(0, 0, new Label("To"));
		mainTable.getFlexCellFormatter().setRowSpan(0, 0, 2);

		m_radioRoot = new RadioButton(RADIO_GROUP_DESTINATION_TYPE,
				"Cards root");
		m_radioRoot.setChecked(true);
		m_radioRoot.addClickListener(new ClickListener() {
			public void onClick(Widget sender) {
				updateUrlDisplay();
			}
		});
		mainTable.setWidget(0, 1, m_radioRoot);

		RadioButton radioCard = new RadioButton(RADIO_GROUP_DESTINATION_TYPE,
				"Card number:");
		radioCard.addClickListener(new ClickListener() {
			public void onClick(Widget sender) {
				updateUrlDisplay();
			}
		});
		mainTable.setWidget(1, 0, radioCard);
		m_cardNumber = new TextBox();
		m_cardNumber.addChangeListener(new ChangeListener() {
			public void onChange(Widget sender) {
				updateUrlDisplay();
			}
		});
		mainTable.setWidget(1, 1, m_cardNumber);

		// 'Http method' section
		mainTable.setWidget(2, 0, new Label("Http method"));
		m_httpMethod = new ListBox(false);
		m_httpMethod.addItem(RestRequestBuilder.Method.GET);
		m_httpMethod.addItem(RestRequestBuilder.Method.PUT);
		m_httpMethod.addItem(RestRequestBuilder.Method.POST);
		m_httpMethod.addItem(RestRequestBuilder.Method.DELETE);
		m_httpMethod.addItem(RestRequestBuilder.Method.HEAD);
		mainTable.setWidget(2, 1, m_httpMethod);

		// 'Content' section
		mainTable.setWidget(3, 0, new Label("Content"));
		m_postText = new TextArea();
		m_postText.setVisibleLines(3);
		m_postText.setCharacterWidth(30);
		mainTable.setWidget(3, 1, m_postText);
		mainTable.getFlexCellFormatter().setColSpan(3, 1, 2);

		// Url display
		mainTable.setWidget(4, 0, new Label("Url"));
		m_urlDisplay = new TextBox();
		updateUrlDisplay();
		mainTable.setWidget(4, 1, m_urlDisplay);
		mainTable.setWidget(4, 2, new Button("Do Http request",
				new ClickListener() {
					public void onClick(Widget sender) {
						doRequest();
					}
				}));

		// Result display
		mainTable.setWidget(5, 0, new Label("Http result"));
		m_httpResult = new TextArea();
		m_httpResult.setReadOnly(true);
		m_httpResult.setVisibleLines(15);
		m_httpResult.setCharacterWidth(60);
		mainTable.setWidget(5, 1, m_httpResult);
		mainTable.getFlexCellFormatter().setColSpan(5, 1, 2);
	}

	private void updateUrlDisplay() {
		if (m_radioRoot.isChecked()) {
			m_urlDisplay.setText("/cards");
		} else {
			m_urlDisplay.setText("/cards/" + m_cardNumber.getText());
		}
	}

	private void doRequest() {

		String httpMethod = m_httpMethod.getValue(m_httpMethod
				.getSelectedIndex());
		RequestBuilder.Method httpMethodObject;

		if (httpMethod.equals(RestRequestBuilder.Method.GET)) {
			doRequest(RestRequestBuilder.GET, null);
		} else if (httpMethod.equals(RestRequestBuilder.Method.POST)) {
			doRequest(RestRequestBuilder.POST, m_postText.getText());
		} else if (httpMethod.equals(RestRequestBuilder.Method.PUT)) {
			doRequest(RestRequestBuilder.PUT, m_postText.getText());
		} else if (httpMethod.equals(RestRequestBuilder.Method.DELETE)) {
			doRequest(RestRequestBuilder.DELETE, m_postText.getText());
		} else if (httpMethod.equals(RestRequestBuilder.Method.HEAD)) {
			doRequest(RestRequestBuilder.HEAD, m_postText.getText());
		} else {
			Window.alert("Unusual error");
		}

	}

	private RequestCallback getCallback() {
		return new RequestCallback() {
			public void onError(Request request, Throwable exception) {
				m_httpResult.setText("Error during Http call: "
						+ exception.toString());
			}

			public void onResponseReceived(Request request, Response response) {
				StringBuffer result = new StringBuffer();
				result.append("Response: ");
				result.append(response.getStatusCode());
				result.append("-");
				result.append(response.getStatusText());
				result.append("\n");
				result.append("Headers-------------------------\n");
				result.append(response.getHeadersAsString());
				result.append("Response text------------------------\n");
				result.append(response.getText());
				result.append("\n");
				m_httpResult.setText(result.toString());
			}
		};
	}

	private void doRequest(RestRequestBuilder.Method httpMethod,
			String postContents) {
		try {
			m_httpResult.setText("Requesting");
			RestRequestBuilder requestBuilder = RestRequestBuilder.create(
					httpMethod, m_urlDisplay.getText(), postContents);
			requestBuilder.sendRequest(getCallback());
		} catch (RequestException e) {
			Window.alert("Can't make request: " + e.toString());
		}
	}
}